import React from 'react';
import {FunnelPlotOutlined} from '@ant-design/icons';
import {Button, Input, Popover, Spin, Tag, Form, message, List, Radio, Col, Row, Space} from 'antd';
import {
    getRandomKey,
    isObjectValEqual,
    sleepFunc,
    isNotEmpty
} from 'jh-utils';
import {forEach, isArray, isEmpty, isFunction, isString, map, pick} from 'lodash-es';

import ButtonComp from '../ButtonComp'
import styles from "../QueryTable/index.module.less";
import {getFilterByType} from "../Base/helper/getFilterByType";
import PropTypes from "prop-types";
import BaseComp from "../Base/BaseComp";
import classNames from 'classnames'
import {filterCodes, getFilterPreview} from "../../components/Base/helper/filterPreview";
import {getContainerFunc} from "../Base/helper/lifeCycle";
import ActivityRadioGroup from "./ActivityRadioGroup";

const {Search} = Input;

class SearchFormComp extends BaseComp {

    static propTypes = {
        /**
         * 默认的表单值
         */
        defaultFormData: PropTypes.object,
        /**
         * 筛选条件的配置，数据结构如下：
         * [
         {
                    compLabel:'标签文本',
                    componentType: '组件类型',
                    fieldName: '属性名称',
                },
         ...
         * ]
         *
         * */
        filterConfig: PropTypes.arrayOf(PropTypes.object)
    };

    formRef = React.createRef();


    initState(props) {
        return {
            formData: props.defaultFormData ? props.defaultFormData : {},//用于临时保存表单数据
            searchParams: props.defaultParams ? props.defaultParams : {}
        }
    }

    componentDidMount() {
        super.componentDidMount();
        this.props.onRef && this.props.onRef(this);
    }

    componentDidUpdate(prevProps, prevState) {
        if (!isObjectValEqual(prevProps.defaultFormData, this.props.defaultFormData)) {
            this.setState({formData: this.props.defaultFormData});
            this.formRef.current.setFieldsValue(this.props.defaultFormData);
        }
    }

    updateFormData(newFormData, afterCb) {
        this.setState({
            formData: {
                ...this.state.formData,
                ...newFormData,
            },
        }, () => {
            afterCb && afterCb(this.state.formData);
            this.formRef.current.setFieldsValue(this.state.formData);
        });
    }

    deleteFields(fields) {
        let fArr = [];
        if (isArray(fields)) {
            fArr = fields;
        } else if (isString(fields)) {
            fArr = fields.split(';');
        }
        let tmpObj = {};
        forEach(fArr, v => {
            if (v) {
                tmpObj[v] = null;
            }
        });
        this.formRef.current.setFieldsValue(tmpObj);
        this.handleOk();
    }

    validateForm(okCb, errCb) {
        this.formRef.current.validateFields().then(values => {
            okCb && okCb(values);
        }).catch(errorInfo => {
            errCb && errCb(errorInfo);
        });
    }

    getSearchFormIns() {
        return this.formRef;
    }

    /**
     * 确认
     */
    handleOk(e, isCancel) {
        const {onOk, onError} = this.props;

        this.formRef.current.validateFields().then(values => {
            const data = {};

            forEach(values, (val, key) => {
                if (val && (
                    [filterCodes.null.code, filterCodes.noNull.code].indexOf(val.comboVal) > -1 ||
                    isNotEmpty(val.compVal)
                )) {
                    data[key] = val;
                } else {
                    data[key] = undefined;
                }
            });

            this.setState({
                formData: data,
            }, () => {
                onOk && onOk(data, isCancel);
            });

        }).catch(errorInfo => {
            onError && onError(errorInfo);
        });
    }

    /**
     * 取消
     */
    handleCancel() {
        // console.log('this.state.formData', this.state.formData);
        this.formRef.current.resetFields();
        // if (this.props.multiAct) {
        isFunction(this.props.onCancel) && (this.props.onCancel());
        // } else {
        //   this.handleOk(null, true);
        // }
    }

    /**
     * 重置
     */
    handleReset() {
        const {onReset} = this.props;
        this.setState({
            formData: {},
        }, () => {
            this.formRef.current.resetFields();
            if (onReset) {
                onReset(this.state.formData);
            }
        });
    }

    mainRender() {
        const {filterConfig, colSpanDefault = 0, formItemPropsDefault} = this.props;
        const formProps = {
            labelCol: {span: 6},
            wrapperCol: {span: 18},
            ...formItemPropsDefault
        };
        // console.log('searchComp:',this.props);
        let formItemComp = (
            <>
                {
                    map(filterConfig, (col, key) => {
                        const compProps = {
                            ...col,
                            colSpan: colSpanDefault,
                            appins: this.props.appins,
                            key: `${col.fieldName}_${key}`,
                            formItemProps: {
                                style: {marginBottom: 16},
                                ...(col.formItemProps || {})
                            },
                            belong: {
                                ...(this.props.belong || {}),
                                search: true,
                                fieldName: col.fieldName,
                            }
                        };
                        return (
                            getFilterByType(col.componentType, compProps)
                        );
                    })
                }
                {
                    this.props.children
                }
            </>
        );
        return (
            <Form ref={this.formRef}
                  component={'div'}
                  className={'form-small'}
                  labelAlign='right' layout="horizontal"
                  initialValues={this.state.formData}
                  {...formProps}>
                {colSpanDefault > 0 ? <Row>{formItemComp}</Row> : formItemComp}
                <div style={{textAlign: 'center', paddingTop: 16, borderTop: '1px solid #e0e0e0'}}>
                    <Space>
                        <Button type='primary'
                            // onClick={this.handleOk.bind(this)}>{this.props.multiActTxt || '查询'}</Button>
                                onClick={this.handleOk.bind(this)}>{this.formatMsgByCn('查询')}</Button>
                        <Button onClick={this.handleCancel.bind(this)}>{this.formatMsgByCn('取消')}</Button>
                        <Button onClick={this.handleReset.bind(this)}>{this.formatMsgByCn('重置')}</Button>
                    </Space>
                </div>
            </Form>
        );
    }
}

const tagStyle = {
    color: '#333',
    marginBottom: 4,
    // borderRadius: 0,
};
const tagSpanStyle = {
    // maxWidth: 150,
    display: 'inline-block',
    overflow: 'hidden',
    float: 'left',
    textOverflow: 'ellipsis',
};

const zIndex = 1030;

export default class SearchComp extends BaseComp {

    static defaultProps = {
        defaultSearchData: null, // Object 默认的搜索条件。数据结构：{ formData: object, search: string}
        customBtn: null, // ReactComponent 自定义的按钮
        needPrev: true, // Boolean 是否需要回显搜索条件
        multiAct: false, // Boolean 是否用于 批量操作（如 批量打印、批量导出）
        defaultOpen: false, // Boolean 是否默认打开搜索表单
        onOk: null, // Function 确认搜索的回调；如：(values: 用于请求接口的数据对象, originalValues: 表单的原始数据对象) => {}
        popoverProps: {}, // Object (选传) Popover 组件的属性值
        prefixSearch: null, // 搜索输入框之前的内容
        suffixSearch: null, // 搜索输入框之后的内容
        isSearchInput: true,//是否需要搜索框
        activityVisible: false, // 是否显示“任务按钮”
        popupContainId: '', // “高级浮层组件”的所属容器 id，默认是 root
    };

    /**
     * 当前搜索条件
     * @type {{ formData: object, search: string, }}
     */
    searchData;
    popoverZIndex;
    searchRef;
    qsTlRef;

    constructor(props) {
        super(props);
        const {defaultSearchData} = props;
        this.searchData = defaultSearchData || {};
        this.popoverZIndex = props.defaultOpen ? zIndex : -1; // 浮层的 z-index 值，1030 表示可见，-1 则一直隐藏
    }

    initState(props) {
        return {
            isOpen: true,
        };
    }

    componentDidMount() {
        isFunction(super.componentDidMount) && super.componentDidMount();
        // 由于搜索表单的浮层默认是打开状态且隐藏起来的，所以如果 this.props.defaultOpen 是关闭的话，就把浮层关闭
        if (!this.props.defaultOpen && this.state.isOpen) {
            this.setState({isOpen: false});
            sleepFunc(300, {}).then(() => {
                // console.log('300 this.popoverZIndex', this.popoverZIndex);
                if (this.props && !this.props.defaultOpen) {
                    this.popoverZIndex = zIndex;
                }
            });
        }

        if (!isEmpty(this.props.defaultParams)) {
            this.initSearchParams();
        }
    }

    componentDidUpdate(prevProps, prevState) {
        isFunction(super.componentDidUpdate) && super.componentDidUpdate(prevProps, prevState);

        if (prevProps.defaultOpen !== this.props.defaultOpen) {
            this.popoverZIndex = this.props.defaultOpen ? zIndex : -1;
            this.setState({
                isOpen: this.props.defaultOpen,
            });
        }

        if (!isObjectValEqual(prevProps.defaultSearchData, this.props.defaultSearchData)) {
            this.searchData = this.props.defaultSearchData || {};
            this.setState({randomKey: getRandomKey()});
        }

        if (!isEmpty(this.props.defaultParams) && !isObjectValEqual(prevProps.defaultParams, this.props.defaultParams)) {
            this.initSearchParams();
        }
    }

    /**
     * 初始化默认参数，如果默认参数存在，
     * 例如：活动按钮分类参数，则请求一次并清空
     */
    initSearchParams() {
        this.setState({
            searchParams: this.props.defaultParams || {}
        });
        window.dvaDispatch({
            type: 'queryTable/clearApp',
            payload: {
                appCode: this.getAppCode()
            },
        });
        this.props.onOk && this.props.onOk(this.props.defaultParams);
    }

    /**
     * 高级查询。点击“查询”
     * @param values object 查询表单的值
     * @param isCancel boolean 是否点击‘取消’按钮之后调用的
     **/
    handleQuery(values, isCancel) {
        this.searchData.formData = {...values};

        if (false === this.props.multiAct) {
            this.setState({
                isOpen: false,
                randomKey: getRandomKey()
            }, () => {
                if (true !== isCancel) {
                    sleepFunc(300, {}).then(() => {
                        this.props.onOk && this.props.onOk(this.searchData);
                    });
                }
            });
        } else {
            this.props.onOk && this.props.onOk(this.searchData);
        }
    }

    handleSearch(value) {
        this.searchData.search = value;
        this.props.onOk && this.props.onOk(this.searchData);
    }

    handleActivityChange(e) {
        if (e.target && e.target.value) {
            const {searchParams} = this.state;
            const newSearchParams = {...searchParams};
            newSearchParams.activity = e.target.value;
            this.setState({
                searchParams: newSearchParams
            });
            this.props.onOk && this.props.onOk(newSearchParams);
        }

    }

    /**
     * 从 values 中提取回显的值
     * @param values object 高级查询表单的值
     **/
    getPreviewFields = (values) => {
        let fields = [];

        if (!isEmpty(values)) {
            // console.log('values', values);
            forEach(values, (valueItem) => {
                // valueItem 的结构 {
                //     comboVal: '条件的值',
                //     compVal: '组件的值',
                //     componentType: '组件类型',
                //     fieldName: '字段名',
                //     label: '字段的文本标签'
                // }

                if (valueItem) {
                    let previewTxt;
                    const {appins} = this.props;
                    if (null !== valueItem.previewValue && undefined !== valueItem.previewValue) {
                        previewTxt = valueItem.previewValue;
                    } else {
                        previewTxt = getFilterPreview(valueItem, {
                            formatMsgByCn: this.formatMsgByCn.bind(this),
                            appins
                        }) || '';
                    }
                    fields.push(previewTxt);
                }
            });
        }
        return fields;
    };

    deleteSearchFields(fields, e) {
        e.stopPropagation();
        e.preventDefault();
        this.searchRef.deleteFields(fields);
    }

    activityBtnRender() {
        const {activityVisible} = this.getProps();
        const {searchParams = {}} = this.state;
        const activity = searchParams.activity;
        const activityTaskCode = searchParams.activityTaskCode;
        return <>
            {/*{activityVisible && <Radio.Group defaultValue={activity || "MY"} value={activity} buttonStyle="solid">*/}
            {/*    <Radio.Button onClick={this.handleActivityChange.bind(this)}*/}
            {/*                  value="MY">{this.formatMsgByCn('我的')}</Radio.Button>*/}
            {/*    <Radio.Button onClick={this.handleActivityChange.bind(this)}*/}
            {/*                  value="TODO">{this.formatMsgByCn('待办')}</Radio.Button>*/}
            {/*    <Radio.Button onClick={this.handleActivityChange.bind(this)}*/}
            {/*                  value="END">{this.formatMsgByCn('已办')}</Radio.Button>*/}
            {/*</Radio.Group>}*/}
            {
                activityVisible && <ActivityRadioGroup
                    {...this.props}
                    activity={activity}
                    activityTaskCode={activityTaskCode}
                    onChange={(filter, newState = {})=>{
                        let  { onOk } = this.props;
                        const { searchParams } = this.state;
                        onOk && onOk({
                            ...searchParams,
                            ...newState,
                            actInfoFilter: filter
                        })
                    }}
                />
            }
        </>
    }

    getCompHeight() {
        if (this.qsTlRef && this.qsTlRef.offsetHeight) {
            // console.log('this.qsTlRef.offsetHeight', this.qsTlRef.offsetHeight);
            return this.qsTlRef.offsetHeight > 0 ? this.qsTlRef.offsetHeight : 70;
        } else {
            return 70;
        }
    }

    /**
     * 获取表单实例
     * */
    getFormIns() {
        if (!isEmpty(this.searchRef) && this.searchRef.getSearchFormIns && isFunction(this.searchRef.getSearchFormIns)) {
            return this.searchRef.getSearchFormIns();
        } else {
            return null;
        }
    }

    mainRender() {
        const {popoverProps, filterConfig} = this.props;
        const {formData} = this.searchData;
        // console.log('formData:',formData);
        const previewFields = this.getPreviewFields(formData);
        let hadPop = !isEmpty(filterConfig); // 有设置搜索条件时，才显示“高级”

        const formContent = !hadPop ? null : (
            <SearchFormComp
                {...pick(this.props, ['colSpanDefault', 'formItemPropsDefault'])}
                onRef={(ref) => {
                    this.searchRef = ref;
                }}
                filterConfig={filterConfig}
                appins={this.props.appins}
                belong={this.props.belong}
                defaultFormData={this.props.defaultSearchData ? this.props.defaultSearchData.formData : undefined}
                // multiAct={this.props.multiAct}
                // multiActTxt={this.props.multiActTxt}
                onOk={this.handleQuery.bind(this)}
                onReset={(values) => {
                    this.searchData.formData = values;
                    this.setState({randomKey: getRandomKey()});
                }}
                onError={(errors, fieldsValue) => {
                    this.searchData.formData = fieldsValue;
                    this.setState({randomKey: getRandomKey(), isOpen: true});
                }}
                onCancel={() => {
                    this.setState({
                        isOpen: false,
                    });
                }}
            >
                {this.props.children}
            </SearchFormComp>
        );
        // const defaultWidth = this.props.styleWidth||450;
        // console.log('this.state.isOpen:',this.state.isOpen);
        return (
            <div style={{
                display: "flex",
                flexFlow: "column",
                justifyContent: "center",
                alignItems: "flex-start"
            }} ref={ref => {
                this.qsTlRef = ref
            }}
            >
                <div className={styles.qsTl}>
                    {
                        // this.props.isSearchInput && (
                        //     <>
                        //         <FileSearchOutlined className={styles.tlIcon}/>
                        //         <span className={styles.tl}>{this.formatMsgByCn('搜索条件')}</span>
                        //     </>
                        // )
                    }
                    {isFunction(this.props.prefixSearch) ? this.props.prefixSearch(this) : this.props.prefixSearch}
                    {
                        this.props.isSearchInput && <Search style={{width: 300}}
                                                            placeholder={this.myFormatMessage('comp.search.placeholder')}
                                                            onSearch={this.handleSearch.bind(this)}
                        />
                    }

                    {
                        isFunction(this.props.suffixSearch) ? this.props.suffixSearch(this) : this.props.suffixSearch
                    }
                    {this.activityBtnRender()}
                    {
                        hadPop && (
                            <Popover visible={this.state.isOpen}
                                     onVisibleChange={visible => {
                                         this.setState({isOpen: visible});
                                     }}
                                     placement={this.props.isSearchInput ? 'bottom' : 'rightTop'}
                                     overlayStyle={{
                                         width: this.props.styleWidth || 500,
                                         zIndex: this.popoverZIndex,
                                         maxWidth: '100%'
                                     }}
                                     content={(
                                         <Spin spinning={true === this.props.loading}>
                                             {formContent}
                                         </Spin>
                                     )}
                                     trigger={'click'}
                                     getPopupContainer={() => getContainerFunc(this)}
                                     {...popoverProps}
                            >

                                <ButtonComp style={{padding: 0}} size={'small'} type={`link`}>
                                    {this.props.isSearchInput ? this.formatMsgByCn('高级查询') :
                                        <>
                                            <span
                                                className={classNames(styles.tl, styles.notSearch)}>{this.formatMsgByCn('高级查询')}</span>
                                        </>
                                    }
                                    {/*{this.state.isOpen === true ? <UpOutlined className={styles.btnIcon}/> : <DownOutlined className={styles.btnIcon}/>}*/}
                                </ButtonComp>
                            </Popover>
                        )
                    }


                    {/*<CustomQuery/>*/}
                </div>
                <div>
                    {
                        map(previewFields, (v, k) => {
                            let pre = '';

                            if (v.isJsx) {
                                pre = (<>
                                    {v.label ? `${v.label}：  ` : ''}
                                    {v.text || ''}
                                </>)
                            } else {
                                pre = v.label ? `${v.label}：  ${v.text}` : (v.text || '');
                            }
                            return (
                                <Tag key={k} style={tagStyle}
                                     title={`${v.isJsx ? '' : pre}`}
                                     closable={true}
                                     color={'blue'}
                                     onClose={this.deleteSearchFields.bind(this, v.fieldNames)}>
                                    <span style={tagSpanStyle}>{pre}</span>
                                </Tag>
                            );
                        })
                    }
                </div>
            </div>
        );
    }
}

/**
 * 自定义查询
 */
// class CustomQuery extends BaseComp {
//
//     state = {
//         isShowModal: false,
//         inputValue: ''
//     };
//
//     handleOk = () => {
//         let gs = getStorage('querySearchData') || {};
//         const {inputValue} = this.state;
//         const {SearchQuery} = this.props;
//         if (inputValue) {
//             gs[inputValue] = this.searchData;
//             setStorage('querySearchData', gs);
//
//             if (isFunction(SearchQuery)) SearchQuery();
//
//             this.setState({searchV: false});
//         } else {
//             message.warn('请输入过滤条件描述')
//         }
//
//     };
//
//     mainRender(context) {
//         const content = (
//             <List
//                 itemLayout="horizontal"
//                 size='small'
//                 // dataSource={this.state.querySearchList}
//                 renderItem={(item) => (
//                     <List.Item
//                         extra={
//                             <CloseOutlined style={{cursor: "pointer"}} onClick={() => {
//                                 // console.log('X',item);
//                                 // let gs = getStorage('querySearchData') || {};
//                                 // delete gs[item.title];
//                                 // setStorage('querySearchData', gs);
//                                 // this.setQueryFromCache();
//                             }}/>
//                         }
//                     >
//                         <List.Item.Meta
//                             title={<a onClick={() => {
//                                 console.log('title', item)
//                                 // this.setSearchData(item.searchData, true, true);
//                                 // this.searchRef.dealfilterConfig(item.searchData)
//                             }}>{item.title}</a>}
//                         />
//                     </List.Item>
//                 )}
//             />
//         );
//
//         return (<>
//
//                 <Popover placement="bottomRight"
//                          title={this.formatMsgByCn('请选择')}
//                          content={content}
//                          trigger="click">
//                     <ButtonComp style={{paddingLeft: 0, paddingRight: 0}} type={`link`}>
//                         {this.formatMsgByCn('自定义查询')}
//                     </ButtonComp>
//                 </Popover>
//
//                 <ModalComp
//                     title="创建自定义查询"
//                     visible={this.state.isShowModal}
//                     // onOk={this.handleOk}
//                     onCancel={() => {
//                         this.setState({isShowModal: false})
//                     }}
//                 >
//                     <InputComp compLabel='过滤条件描述' onChange={({target}) => {
//                         this.setState({inputValue: target.value})
//                     }}/>
//                 </ModalComp>
//             </>
//         )
//     }
// }
